#include  "Typedef.h"
#include  "macros.h"

#include  "CC2500.h"
#include  "CC1100.h"
#include  "Timer.h"

#include  "Phy_Frame.h"
#include  "Wirelessprotocol.h"
#include  "GlobalMethod.h"
#include  "eSeal_Management.h"
#include  "string.h"
#include  "stdlib.h"


#define  FRAME_P2P_DOWN_DATA_POS_PROTOCOLID         (0)
#define  FRAME_P2P_DOWN_DATA_POS_DATAOPTION         (FRAME_P2P_DOWN_DATA_POS_PROTOCOLID + 1)
#define  FRAME_P2P_DOWN_DATA_POS_VENDERID           (FRAME_P2P_DOWN_DATA_POS_DATAOPTION + 1)
#define  FRAME_P2P_DOWN_DATA_POS_ESEALID            (FRAME_P2P_DOWN_DATA_POS_VENDERID + FRAME_DATA_LTH_VENDORID)
#define  FRAME_P2P_DOWN_DATA_POS_READERID           (FRAME_P2P_DOWN_DATA_POS_ESEALID + FRAME_DATA_LTH_ESEALID)
#define  FRAME_P2P_DOWN_DATA_POS_COMMAND            (FRAME_P2P_DOWN_DATA_POS_READERID + FRAME_DATA_LTH_READERID)
#define  FRAME_P2P_DOWN_DATA_POS_MINLASTTIME        (FRAME_P2P_DOWN_DATA_POS_COMMAND + 1)
#define  FRAME_P2P_DOWN_DATA_POS_MAXLASTTIME        (FRAME_P2P_DOWN_DATA_POS_MINLASTTIME + 2)
#define  FRAME_P2P_DOWN_DATA_POS_PARALTH            (FRAME_P2P_DOWN_DATA_POS_MAXLASTTIME + 2)
#define  FRAME_P2P_DOWN_DATA_POS_PARA               (FRAME_P2P_DOWN_DATA_POS_PARALTH + 1)

#define  FRAME_BROADCAST_DOWN_DATA_POS_PROTOCOLID    (0)
#define  FRAME_BROADCAST_DOWN_DATA_POS_DATAOPTION    (FRAME_BROADCAST_DOWN_DATA_POS_PROTOCOLID + 1)
#define  FRAME_BROADCAST_DOWN_DATA_POS_READERID      (FRAME_BROADCAST_DOWN_DATA_POS_DATAOPTION + 1)
#define  FRAME_BROADCAST_DOWN_DATA_POS_COMMAND       (FRAME_BROADCAST_DOWN_DATA_POS_READERID + FRAME_DATA_LTH_READERID)
#define  FRAME_BROADCAST_DOWN_DATA_POS_PARALTH       (FRAME_BROADCAST_DOWN_DATA_POS_COMMAND + 1)
#define  FRAME_BROADCAST_DOWN_DATA_POS_PARA          (FRAME_BROADCAST_DOWN_DATA_POS_PARALTH + 1)

#define  FRAME_P2P_UP_DATA_POS_PROTOCOLID           (0)
#define  FRAME_P2P_UP_DATA_POS_ESEALSTATUS          (FRAME_P2P_UP_DATA_POS_PROTOCOLID + 1)
#define  FRAME_P2P_UP_DATA_POS_READERID             (FRAME_P2P_UP_DATA_POS_ESEALSTATUS + 2)
#define  FRAME_P2P_UP_DATA_POS_VENDERID             (FRAME_P2P_UP_DATA_POS_READERID + FRAME_DATA_LTH_READERID)
#define  FRAME_P2P_UP_DATA_POS_ESEALID              (FRAME_P2P_UP_DATA_POS_VENDERID + FRAME_DATA_LTH_VENDORID)
#define  FRAME_P2P_UP_DATA_POS_COMMAND              (FRAME_P2P_UP_DATA_POS_ESEALID + FRAME_DATA_LTH_ESEALID)
#define  FRAME_P2P_UP_DATA_POS_DATALTH              (FRAME_P2P_UP_DATA_POS_COMMAND + 1)
#define  FRAME_P2P_UP_DATA_POS_DATA                 (FRAME_P2P_UP_DATA_POS_DATALTH + 1)

#define  FRAME_LF_WAKEUP_LTH                        (0x07)
#define  FRAME_LF_DOWN_DATA_POS_PROTOCOLID          (0)
#define  FRAME_LF_DOWN_DATA_POS_DATAOPTION          (FRAME_LF_DOWN_DATA_POS_PROTOCOLID + 1)
#define  FRAME_LF_DOWN_DATA_POS_READERID            (FRAME_LF_DOWN_DATA_POS_DATAOPTION + 1)
#define  FRAME_LF_DOWN_DATA_POS_CHANNEL             (FRAME_LF_DOWN_DATA_POS_READERID + FRAME_DATA_LTH_READERID)
#define  FRAME_LF_DOWN_DATA_POS_CRC                 (FRAME_LF_DOWN_DATA_POS_CHANNEL + 1)

#define  WIRELESSPROTOCOL_DOWN_ID                           (0xA0)
#define  WIRELESSPROTOCOL_UP_ID                             (0x0A)

#define  FRAME_BUILD_OK                             (0x00)
#define  FRAME_BUILD_ERR                            (0x01)

#define  FRAME_SEND_OK                              (0x00)
#define  FRAME_SEND_ERR_FAILED                      (0x01)  
#define  FRAME_SEND_ERR_MISSPATH                    (0x02)


#define  DATA_OPTION_TANSTYPE_BIT                   (1)
#define  DATA_OPTION_MINLASTTIME_BIT                (2)
#define  DATA_OPTION_MAXLASTTIME_BIT                (3)

#define  FRAME_TRANS_TYPE_P2P                       (0x01)
#define  FRAME_TRANS_TYPE_BROADCAST                 (0x02)     

#define  FRAME_P2P_DOWN_DEFAULT_LTH                 (16)
#define  FRAME_BROADCAST_DOWN_DEFAULT_LTH           (6)
#define  FRAME_P2P_UP_DEFAULT_LTH                   (13)

EEPROM  INT8U   __eeprom_CurrentReaderID[FRAME_DATA_LTH_READERID] = {0x80 , 0x01};
INT8U   CurrentReaderID[FRAME_DATA_LTH_READERID] = {0x80 , 0x01};

INT8U   PacketTansOK = FALSE;
INT8U   FrameParseOK = TRUE;

static  PHY_FRAME  TransPacket;


PHY_FRAME* BuildP2PPacket(INT8U* pVendorID , INT8U* pESealID , INT8U* pReaderID , 
                          INT8U Cmd ,INT16U MinLastTime , INT16U MaxLastTime , 
                          INT8U ParaLth , INT8U* pPara ,INT8U* err);

PHY_FRAME* BuildBroadcastPacket(INT8U* pReaderID , INT8U Cmd ,
                                INT8U ParaLth , INT8U* pPara ,INT8U* err);

INT8U  SendPacket(PHY_FRAME* pTranspacket , INT8U WirePath);

void   GetData(WIRELESSPROTOCOL_P2P_UP_FRAME* pRecvFrame, INT8U *pData);  

void   GetVenderID(INT8U* pVenderID ,PHY_FRAME* pRecvPacket);
void   GeteSealID(INT8U* peSealID ,PHY_FRAME* pRecvPacket);
void   GetReaderID(INT8U* pReaderID ,PHY_FRAME* pRecvPacket);
INT8U  GetDataLength(PHY_FRAME* pRecvPacket);
INT8U  GetCommand(PHY_FRAME* pRecvPacket);
INT8U  CheckCRC(PHY_FRAME* pRecvPacket);     
INT8U  CheckReaderID(PHY_FRAME* pRecvPacket);

#define  COMMAND_SEND_OK               0x01
#define  COMMAND_SEND_FAILED           0x02

INT8U eSeal_SendCmd_Sleep(INT8U* pVendorID , INT8U* peSealID , INT8U* err)
{
   PHY_FRAME* pPHY_Frame;
   
   ASSERT(pVendorID);
   ASSERT(peSealID);
   
   pPHY_Frame = BuildP2PPacket(pVendorID , peSealID , CurrentReaderID , 
                               WIRELESSPROTOCOL_P2P_CMD_SLEEP , 0 , 0 ,
                               0 , NULL , err);
   if(FRAME_BUILD_OK == *err)
   {
      *err = SendPacket(pPHY_Frame , PHY_USE_CC2500);
      if(FRAME_SEND_OK == *err)
        return COMMAND_SEND_OK;
      else
        return COMMAND_SEND_FAILED;
   }
   else
     return COMMAND_SEND_FAILED;
}

INT8U eSeal_SendCmd_ReadRTC(INT8U* pVendorID,INT8U* peSealID , INT8U* err)
{
   PHY_FRAME* pPHY_Frame;
   
   ASSERT(pVendorID);
   ASSERT(peSealID);
   
   pPHY_Frame = BuildP2PPacket(pVendorID , peSealID , CurrentReaderID , 
                               WIRELESSPROTOCOL_P2P_CMD_READ_RTC , 0 , 0 ,
                               0 , NULL , err);
   if(FRAME_BUILD_OK == *err)
   {
      *err = SendPacket(pPHY_Frame , PHY_USE_CC2500);
      if(FRAME_SEND_OK == *err)
        return COMMAND_SEND_OK;
      else
        return COMMAND_SEND_FAILED;
   }
   else
     return COMMAND_SEND_FAILED;
}
#define  AUTHORIZE_CODE_SIZE           (4)

INT8U eSeal_SendCmd_Authorize(INT8U* pVendorID , INT8U* peSealID , INT8U* pAuthorizeCode , INT8U* err)
{
   PHY_FRAME* pPHY_Frame;
   
   ASSERT(pVendorID);
   ASSERT(peSealID);
   ASSERT(pAuthorizeCode);
   
   pPHY_Frame = BuildP2PPacket(pVendorID , peSealID , CurrentReaderID , 
                               WIRELESSPROTOCOL_P2P_CMD_AUTHORIZE , 0 , 0 ,
                               AUTHORIZE_CODE_SIZE , pAuthorizeCode , err);
   if(FRAME_BUILD_OK == *err)
   {
      *err = SendPacket(pPHY_Frame , PHY_USE_CC2500);
      if(FRAME_SEND_OK == *err)
        return COMMAND_SEND_OK;
      else
        return COMMAND_SEND_FAILED;
   }
   else
     return COMMAND_SEND_FAILED;
}

#define  CMD_HANDLE_ESEAL_OPTION_SEAL_PARA_LTH       (0x04)
#define  CMD_HANDLE_ESEAL_OPTION_OPEN_PARA_LTH       (0x04)
#define  CMD_HANDLE_ESEAL_OPTION_CLOSE_PARA_LTH      (0x04)
#define  CMD_HANDLE_ESEAL_OPTION_UNSEAL_PARA_LTH     (0x04)
#define  CMD_HANDLE_ESEAL_OPTION_CHECKRTC_PARA_LTH   (0x08)

INT8U eSeal_SendCmd_HandleeSeal(INT8U* pVendorID , INT8U* peSealID , 
                                INT8U* pAuthorizeCode , INT8U OptionType , INT8U* err)
{
   PHY_FRAME* pPHY_Frame;
   
   INT8U DataLth;
   INT8U TempData[8];
   
   ASSERT(pVendorID);
   ASSERT(peSealID);
   ASSERT(pAuthorizeCode);
   
   switch(OptionType)
   {
   case CMD_HANDLE_ESEAL_OPTION_SEAL:    
   case CMD_HANDLE_ESEAL_OPTION_OPEN:
   case CMD_HANDLE_ESEAL_OPTION_CLOSE:
   case CMD_HANDLE_ESEAL_OPTION_UNSEAL:
     memcpy(TempData , pAuthorizeCode , CMD_HANDLE_ESEAL_OPTION_SEAL_PARA_LTH);
     DataLth = CMD_HANDLE_ESEAL_OPTION_SEAL_PARA_LTH;
     break;
   case CMD_HANDLE_ESEAL_OPTION_CHECKRTC:
     {
       INT32U Time;
       Time = GetRTCTime();
       memcpy(TempData , pAuthorizeCode , CMD_HANDLE_ESEAL_OPTION_SEAL_PARA_LTH);
       memcpy(TempData + CMD_HANDLE_ESEAL_OPTION_SEAL_PARA_LTH, 
              (INT8U*)(&Time) , 
              CMD_HANDLE_ESEAL_OPTION_SEAL_PARA_LTH);
       DataLth = CMD_HANDLE_ESEAL_OPTION_CHECKRTC_PARA_LTH;
     }
     break;
   default:
     break;
   }
   pPHY_Frame = BuildP2PPacket(pVendorID , peSealID , CurrentReaderID , 
                               WIRELESSPROTOCOL_P2P_CMD_HANDLE_ESEAL , 0 , 0 ,
                               DataLth , TempData , err);
   if(FRAME_BUILD_OK == *err)
   {
      *err = SendPacket(pPHY_Frame , PHY_USE_CC2500);
      if(FRAME_SEND_OK == *err)
        return COMMAND_SEND_OK;
      else
        return COMMAND_SEND_FAILED;
   }
   else
     return COMMAND_SEND_FAILED;
}

#define  CMD_READ_PARA_OPTION_PARA_LTH       (0x01)

INT8U eSeal_SendCmd_ReadPara(INT8U* pVendorID , INT8U* peSealID , 
                             INT8U OptionType , INT8U* err)
{
   PHY_FRAME* pPHY_Frame;
   
   ASSERT(pVendorID);
   ASSERT(peSealID);
   
   pPHY_Frame = BuildP2PPacket(pVendorID , peSealID , CurrentReaderID , 
                               WIRELESSPROTOCOL_P2P_CMD_READ_PARA , 0 , 0 ,
                               CMD_READ_PARA_OPTION_PARA_LTH , &OptionType , err);
   if(FRAME_BUILD_OK == *err)
   {
      *err = SendPacket(pPHY_Frame , PHY_USE_CC2500);
      if(FRAME_SEND_OK == *err)
        return COMMAND_SEND_OK;
      else
        return COMMAND_SEND_FAILED;
   }
   else
     return COMMAND_SEND_FAILED;
}

#define  CMD_READ_EVENT_RECORD_OPTION_PARA_LTH   (0x02)

INT8U eSeal_SendCmd_ReadEventRecord(INT8U* pVendorID , INT8U* peSealID , 
                                    INT16U RecordNo , INT8U* err)
{
   PHY_FRAME* pPHY_Frame;
   
   ASSERT(pVendorID);
   ASSERT(peSealID);
   
   pPHY_Frame = BuildP2PPacket(pVendorID , peSealID , CurrentReaderID , 
                               WIRELESSPROTOCOL_P2P_CMD_READ_EVENT_RECORD , 0 , 0 ,
                               CMD_READ_EVENT_RECORD_OPTION_PARA_LTH , (INT8U*)(&RecordNo) , err);
   if(FRAME_BUILD_OK == *err)
   {
      *err = SendPacket(pPHY_Frame , PHY_USE_CC2500);
      if(FRAME_SEND_OK == *err)
        return COMMAND_SEND_OK;
      else
        return COMMAND_SEND_FAILED;
   }
   else
     return COMMAND_SEND_FAILED;
}

#define  CMD_READ_EVENT_NUM_OPTION_PARA_LTH   (0x00)

INT8U eSeal_SendCmd_ReadEventNum(INT8U* pVendorID , INT8U* peSealID , INT8U* err)
{
   PHY_FRAME* pPHY_Frame;
   
   ASSERT(pVendorID);
   ASSERT(peSealID);
   
   pPHY_Frame = BuildP2PPacket(pVendorID , peSealID , CurrentReaderID , 
                               WIRELESSPROTOCOL_P2P_CMD_READ_EVENT_NUM , 0 , 0 ,
                               CMD_READ_EVENT_NUM_OPTION_PARA_LTH , NULL , err);
   if(FRAME_BUILD_OK == *err)
   {
      *err = SendPacket(pPHY_Frame , PHY_USE_CC2500);
      if(FRAME_SEND_OK == *err)
        return COMMAND_SEND_OK;
      else
        return COMMAND_SEND_FAILED;
   }
   else
     return COMMAND_SEND_FAILED;
}

#define  CMD_READ_PORT_INOUT_OPTION_PARA_LTH   (0x01)

INT8U eSeal_SendCmd_PortInOut(INT8U* pVendorID , INT8U* peSealID , INT8U InOut,INT8U* err)
{
   PHY_FRAME* pPHY_Frame;
   
   ASSERT(pVendorID);
   ASSERT(peSealID);
   
   pPHY_Frame = BuildP2PPacket(pVendorID , peSealID , CurrentReaderID , 
                               WIRELESSPROTOCOL_P2P_CMD_PORT_INOUT , 0 , 0 ,
                               CMD_READ_PORT_INOUT_OPTION_PARA_LTH , &InOut , err);
   if(FRAME_BUILD_OK == *err)
   {
      *err = SendPacket(pPHY_Frame , PHY_USE_CC2500);
      if(FRAME_SEND_OK == *err)
        return COMMAND_SEND_OK;
      else
        return COMMAND_SEND_FAILED;
   }
   else
     return COMMAND_SEND_FAILED;
}

#define  CMD_READ_STATUS_OPTION_PARA_LTH   (0x00)

INT8U eSeal_SendCmd_ReadStatus(INT8U* pVendorID , INT8U* peSealID ,INT8U* err)
{
   PHY_FRAME* pPHY_Frame;
   
   ASSERT(pVendorID);
   ASSERT(peSealID);
   
   pPHY_Frame = BuildP2PPacket(pVendorID , peSealID , CurrentReaderID , 
                               WIRELESSPROTOCOL_P2P_CMD_READ_STATUS , 0 , 0 ,
                               CMD_READ_STATUS_OPTION_PARA_LTH , NULL , err);
   if(FRAME_BUILD_OK == *err)
   {
      *err = SendPacket(pPHY_Frame , PHY_USE_CC2500);
      if(FRAME_SEND_OK == *err)
        return COMMAND_SEND_OK;
      else
        return COMMAND_SEND_FAILED;
   }
   else
     return COMMAND_SEND_FAILED;
}

#define  CMD_PERIOD_SEND_ONOFF_OPTION_PARA_LTH   (0x02)

INT8U eSeal_SendCmd_PeriodSend(INT8U* pVendorID , INT8U* peSealID ,INT8U bOnOff, INT8U Period , INT8U* err)
{
   PHY_FRAME* pPHY_Frame;
   
   INT8U  DataTemp[2];
   
   ASSERT(pVendorID);
   ASSERT(peSealID);
   
   DataTemp[0] = bOnOff;
   DataTemp[1] = Period;
   pPHY_Frame = BuildP2PPacket(pVendorID , peSealID , CurrentReaderID , 
                               WIRELESSPROTOCOL_P2P_CMD_PERIOD_SEND_ONOFF , 0 , 0 ,
                               CMD_PERIOD_SEND_ONOFF_OPTION_PARA_LTH , DataTemp , err);
   if(FRAME_BUILD_OK == *err)
   {
      *err = SendPacket(pPHY_Frame , PHY_USE_CC2500);
      if(FRAME_SEND_OK == *err)
        return COMMAND_SEND_OK;
      else
        return COMMAND_SEND_FAILED;
   }
   else
     return COMMAND_SEND_FAILED;
}

#define  CMD_COLLECT_OPTION_PARA_LTH   (0x03)

INT8U eSeal_SendCmd_Collect(INT8U CollectRule , INT8U* err)
{
   PHY_FRAME* pPHY_Frame;
   
   const INT16U WindowSize_ms = 200;
   INT8U  DataTemp[3];
    
   memcpy(DataTemp , (INT8U*)(&WindowSize_ms) , 2);
   DataTemp[2] = CollectRule;
   pPHY_Frame = BuildBroadcastPacket( CurrentReaderID , 
                                       WIRELESSPROTOCOL_BROADCAST_CMD_COLLECT,
                                       CMD_COLLECT_OPTION_PARA_LTH , DataTemp , err);
   if(FRAME_BUILD_OK == *err)
   {
      *err = SendPacket(pPHY_Frame , PHY_USE_CC2500);
      if(FRAME_SEND_OK == *err)
        return COMMAND_SEND_OK;
      else
        return COMMAND_SEND_FAILED;
   }
   else
     return COMMAND_SEND_FAILED;
}


INT8U  eSeal_SendCmd_LowFrequencyWakeUp(INT8U Channel , INT8U* err)
{
  INT8U TempData[FRAME_LF_WAKEUP_LTH];
  INT16U CrcCode16;
  
  TempData[FRAME_LF_DOWN_DATA_POS_PROTOCOLID] = WIRELESSPROTOCOL_DOWN_ID;
  TempData[FRAME_LF_DOWN_DATA_POS_DATAOPTION] = 0xff;
  memcpy(&TempData[FRAME_LF_DOWN_DATA_POS_READERID] , CurrentReaderID, FRAME_DATA_LTH_READERID);
  TempData[FRAME_LF_DOWN_DATA_POS_CHANNEL] = Channel;
  CrcCode16 = Crc16(TempData , FRAME_LF_WAKEUP_LTH - 2);
  memcpy(&TempData[FRAME_LF_DOWN_DATA_POS_CRC] , (INT8U*)(&CrcCode16) , 2);
  
  
  memcpy(TransPacket.PhyFrame , TempData , FRAME_LF_WAKEUP_LTH);
  TransPacket.FrameLength = FRAME_LF_WAKEUP_LTH;


  *err = SendPacket(&TransPacket , PHY_USE_CC1100);
  if (FRAME_SEND_OK == *err)
  {
     return COMMAND_SEND_OK;
  } 
  else
  {
     return COMMAND_SEND_FAILED;
  }
}

PHY_FRAME* BuildP2PPacket(INT8U* pVendorID , INT8U* peSealID , INT8U* pReaderID , 
                          INT8U Cmd ,INT16U MinLastTime , INT16U MaxLastTime , 
                          INT8U ParaLth , INT8U* pPara ,INT8U* err)
{
  WIRELESSPROTOCOL_P2P_DOWN_FRAME*  pTansPacket; 
  INT8U  DataOption = 0;
  INT8U  PacketLth = FRAME_P2P_DOWN_DEFAULT_LTH + ParaLth;
  
  ASSERT(pVendorID);
  ASSERT(peSealID);
  ASSERT(pReaderID);
  
  *err = FRAME_BUILD_OK;
  
  pTansPacket = (WIRELESSPROTOCOL_P2P_DOWN_FRAME*)TransPacket.PhyFrame;
  
  //Set protocol id
  pTansPacket->ProtocolID = WIRELESSPROTOCOL_DOWN_ID;
  
  //Set data option 
  DataOption |= BV(DATA_OPTION_TANSTYPE_BIT);
  
  if(MaxLastTime)
  {
     DataOption |= BV(DATA_OPTION_MINLASTTIME_BIT);
     pTansPacket->MaxCmdLastTime = MaxLastTime;
  }
  else
  {
     pTansPacket->MaxCmdLastTime = 0;
  }
  if(MinLastTime)  
  {
      DataOption |= BV(DATA_OPTION_MAXLASTTIME_BIT);
      pTansPacket->MinCmdLastTime = MinLastTime;
  }
  else
  {
      pTansPacket->MinCmdLastTime = 0;
  }
  pTansPacket-> PacketOption = DataOption;
  
  //Set VendoID,eSealID,ReaderID 
  if((pVendorID) && (peSealID) && (pReaderID))
  {
     memcpy(pTansPacket->VendorID , pVendorID , FRAME_DATA_LTH_VENDORID);
     memcpy(pTansPacket->eSealID , peSealID , FRAME_DATA_LTH_ESEALID);
     memcpy(pTansPacket->ReaderID , pReaderID , FRAME_DATA_LTH_READERID);
  }
  else
  {
     *err = FRAME_BUILD_ERR;
  }
  //Set command code
  pTansPacket->Command = Cmd;
  
  //Set parameter length and parameter
  pTansPacket->ParameterLth = ParaLth;
  if(ParaLth)
  {
    ASSERT(pPara);
    memcpy(&TransPacket.PhyFrame[FRAME_P2P_DOWN_DATA_POS_PARA] , pPara , ParaLth);
  }
  //Calc CRC
  *(INT16U*)(&TransPacket.PhyFrame[FRAME_P2P_DOWN_DATA_POS_PARA + ParaLth]) = Crc16(TransPacket.PhyFrame,PacketLth);
  //Set frame length 
  TransPacket.FrameLength = PacketLth + 2;
  return (&TransPacket);
}



PHY_FRAME* BuildBroadcastPacket(INT8U* pReaderID , INT8U Cmd ,
                                INT8U ParaLth , INT8U* pPara ,INT8U* err)
{
  WIRELESSPROTOCOL_BROADCAST_DOWN_FRAME*  pTansPacket; 
  INT8U  DataOption = 0;
  INT8U  PacketLth = FRAME_BROADCAST_DOWN_DEFAULT_LTH + ParaLth;
  
  *err = FRAME_BUILD_OK;
  
  pTansPacket = (WIRELESSPROTOCOL_BROADCAST_DOWN_FRAME*)TransPacket.PhyFrame;
  //pTansPacket->pParameter = &TransPacket.PhyFrame[FRAME_P2P_DOWN_DATA_POS_PARA];
  //Set protocol id
  pTansPacket->ProtocolID = WIRELESSPROTOCOL_DOWN_ID;
  
  //Set data option 
  DataOption &= ~BV(DATA_OPTION_TANSTYPE_BIT);     

  pTansPacket-> PacketOption = DataOption;
  
  //Set VendoID,eSealID,ReaderID 
  if((pReaderID))
  {
     memcpy(pTansPacket->ReaderID , pReaderID , FRAME_DATA_LTH_READERID);
  }
  else
  {
     *err = FRAME_BUILD_ERR;
  }
  //Set command code
  pTansPacket->Command = Cmd;
  
  //Set parameter length and parameter
  pTansPacket->ParameterLth = ParaLth;
  if(ParaLth)
  {
    ASSERT(pPara);
    memcpy(&TransPacket.PhyFrame[FRAME_BROADCAST_DOWN_DATA_POS_PARA] , pPara , ParaLth);
  }
  //Calc CRC
  *(INT16U*)(&TransPacket.PhyFrame[FRAME_BROADCAST_DOWN_DATA_POS_PARA + ParaLth]) = Crc16(TransPacket.PhyFrame,PacketLth);
  //Set frame length
  TransPacket.FrameLength = PacketLth + 2;
  return (&TransPacket);
}

INT8U  SendPacket(PHY_FRAME* pTranspacket , INT8U WirePath)
{
   INT8U err;
   switch(WirePath)
   {
   case PHY_USE_CC2500:
     ASSERT(pTranspacket);
     err =  CC2500_Transmit(GET_TX_PHY_FRAME_ADDR_P(pTranspacket), GET_TX_PHY_FRAME_LTH_P(pTranspacket),CC2500_TX_TYPE_RANDOM);
     break;
   case PHY_USE_CC1100:
     ASSERT(pTranspacket);
     err =  CC1100_Transmit(GET_TX_PHY_FRAME_ADDR_P(pTranspacket), GET_TX_PHY_FRAME_LTH_P(pTranspacket),CC1100_TX_TYPE_RANDOM);
     break;
   default:
     err =  FRAME_SEND_ERR_MISSPATH;
     break;
   }
   return err;
}




#define  CMD_READ_PARA_OPTION_FW_VERSION                        (0x04)
#define  CMD_READ_PARA_OPTION_PWIRELESSPROTOCOL_VERSION         (0x05)
#define  CMD_READ_PARA_OPTION_EVENTS_NUM                        (0x06)
#define  CMD_READ_PARA_OPTION_COLLECT_OVERTIME                  (0x07)
#define  CMD_READ_PARA_OPTION_P2P_OVERTIME                      (0x08)


INT8U  ParseP2PPacket(WIRELESSPROTOCOL_P2P_UP_FRAME* pRecvFrame , INT8U* perr)
{

   INT8U err;
   ESEAL_DETAIL* peSeal = NULL;
   ESEAL_DATA*   peSealData = NULL;
   INT16U  DataType;

   ASSERT(pRecvFrame);

   FrameParseOK = FALSE;  
   err = FRAME_PARSE_ERR;
 
   peSeal = eSeal_Get_eSealObj();

   switch(pRecvFrame->Command)
   {
   case WIRELESSPROTOCOL_P2P_CMD_SLEEP:
        err =  FRAME_PARSE_OK;
     break;
   case WIRELESSPROTOCOL_P2P_CMD_READ_PARA:
        
        DataType = GET_ESEAL_DATA_TYPE(pRecvFrame->Command , pRecvFrame->pData[0]);
        peSealData = eSealDataTable_Find_TypeData(peSeal , DataType);
        if (peSealData == NULL)
        {
           eSealDataTable_Add_DataObj(peSeal , DataType , pRecvFrame->DataLth , pRecvFrame->pData);
           err = FRAME_PARSE_OK;
        }
        else
        {
          //err = FRAME_PARSE_DATA_EXIST;
          err = FRAME_PARSE_OK;
        }
        
     break;
   case WIRELESSPROTOCOL_P2P_CMD_READ_RTC:

       DataType = GET_ESEAL_DATA_TYPE(pRecvFrame->Command , 0x00);
       peSealData = eSealDataTable_Find_TypeData(peSeal , DataType);
       if (peSealData == NULL)
       {
           eSealDataTable_Add_DataObj(peSeal , DataType , pRecvFrame->DataLth , pRecvFrame->pData);
           err = FRAME_PARSE_OK;
       }
       else
       {
           //err = FRAME_PARSE_DATA_EXIST;
           eSealDataTable_Update_DataObj(peSealData , pRecvFrame->DataLth , pRecvFrame->pData);
           err = FRAME_PARSE_OK;
       }
     break;
   case WIRELESSPROTOCOL_P2P_CMD_AUTHORIZE:
       err =  FRAME_PARSE_OK;
     break;
   case WIRELESSPROTOCOL_P2P_CMD_HANDLE_ESEAL:
       err =  FRAME_PARSE_OK;
     break;
   case WIRELESSPROTOCOL_P2P_CMD_READ_EVENT_RECORD:
       if (peSeal)
       {
          if(pRecvFrame->pData[1])
          {
            DataType = GET_ESEAL_DATA_TYPE(pRecvFrame->Command , pRecvFrame->pData[1]);
            peSealData = eSealDataTable_Find_TypeData(peSeal , DataType);
            if(peSealData == NULL)
                eSealDataTable_Add_DataObj(peSeal , DataType , pRecvFrame->DataLth , pRecvFrame->pData);
            else
                eSealDataTable_Update_DataObj(peSealData , pRecvFrame->DataLth , pRecvFrame->pData);
            err =  FRAME_PARSE_OK; 
          }
       }
       else
       {
          //err =  FRAME_PARSE_OK;
       }
       break;
   case WIRELESSPROTOCOL_P2P_CMD_READ_EVENT_NUM:
       DataType = GET_ESEAL_DATA_TYPE(pRecvFrame->Command , 0);
       peSealData = eSealDataTable_Find_TypeData(peSeal , DataType);
       if (peSealData == NULL)
       {
           
           eSealDataTable_Add_DataObj(peSeal , DataType , pRecvFrame->DataLth , pRecvFrame->pData);
           err =  FRAME_PARSE_OK;
       }
       else
       {
           eSealDataTable_Update_DataObj(peSealData , pRecvFrame->DataLth , pRecvFrame->pData);  
           err = FRAME_PARSE_DATA_EXIST;
           err = FRAME_PARSE_OK;
       }
     break;
   case WIRELESSPROTOCOL_P2P_CMD_PORT_INOUT:
        err =  FRAME_PARSE_OK;
     break;
   case WIRELESSPROTOCOL_P2P_CMD_READ_STATUS:
     err =  FRAME_PARSE_OK;
     break;
   case WIRELESSPROTOCOL_P2P_CMD_PERIOD_SEND_ONOFF:
     err =  FRAME_PARSE_OK;
     break;
   case WIRELESSPROTOCOL_BROADCAST_CMD_COLLECT:
     err =  FRAME_PARSE_OK;
     break;
   default:
     break;
   }
   
   FrameParseOK = TRUE;
   
   return err;
}

INT8U  Packet2Frame(WIRELESSPROTOCOL_P2P_UP_FRAME* pRecvFrame , PHY_FRAME* pRecvPacket)
{
   INT8U err = PACKET_TANS_OK;
   
   ASSERT(pRecvFrame);
   ASSERT(pRecvPacket);
   
   PacketTansOK = FALSE;
   
   if(TRUE == FrameParseOK)
   {
     if(TRUE == CheckCRC(pRecvPacket))
     {
        if(CheckReaderID(pRecvPacket))
        {
           pRecvFrame->ProtocolID = pRecvPacket->PhyFrame[FRAME_P2P_UP_DATA_POS_PROTOCOLID];
           pRecvFrame->eSealStatus =*(INT16U*)(&pRecvPacket->PhyFrame[FRAME_P2P_UP_DATA_POS_ESEALSTATUS]);
          
           
           memcpy(pRecvFrame->ReaderID , &pRecvPacket->PhyFrame[FRAME_P2P_UP_DATA_POS_READERID] , FRAME_DATA_LTH_READERID);
           memcpy(pRecvFrame->VendorID , &pRecvPacket->PhyFrame[FRAME_P2P_UP_DATA_POS_VENDERID] , FRAME_DATA_LTH_VENDORID);
           memcpy(pRecvFrame->eSealID , &pRecvPacket->PhyFrame[FRAME_P2P_UP_DATA_POS_ESEALID] , FRAME_DATA_LTH_ESEALID);
         
           pRecvFrame->Command = pRecvPacket->PhyFrame[FRAME_P2P_UP_DATA_POS_COMMAND];
           pRecvFrame->DataLth = pRecvPacket->PhyFrame[FRAME_P2P_UP_DATA_POS_DATALTH];
         
         
           if(pRecvFrame->DataLth)
           {
              if(pRecvFrame->pData)
                free(pRecvFrame->pData);
            
              pRecvFrame->pData = (INT8U*)malloc(pRecvFrame->DataLth);
              memcpy(pRecvFrame->pData , &pRecvPacket->PhyFrame[FRAME_P2P_UP_DATA_POS_DATA] , pRecvFrame->DataLth);
           }
        }
        else
        {
           err = PACKET_TANS_ERR_READER_MISSMATCH;
        }
     }
     else
     {
        err = PACKET_TANS_ERR_CRC;
     }
   }
   else
   {
      err = PACKET_TANS_ERR_WAIT_PARSE;
   }
   
   PacketTansOK = TRUE;
   
   return err;
}

void  GetVenderID(INT8U* pVenderID ,PHY_FRAME* pRecvPacket)
{
   WIRELESSPROTOCOL_P2P_UP_FRAME* pRecvFrame = (WIRELESSPROTOCOL_P2P_UP_FRAME*)pRecvPacket->PhyFrame;
   
   ASSERT(pRecvFrame);
   ASSERT(pVenderID);  

   memcpy( pVenderID, pRecvFrame->VendorID , FRAME_DATA_LTH_VENDORID);
}

void  GeteSealID(INT8U* peSealID ,PHY_FRAME* pRecvPacket)
{
   WIRELESSPROTOCOL_P2P_UP_FRAME* pRecvFrame = (WIRELESSPROTOCOL_P2P_UP_FRAME*)pRecvPacket->PhyFrame;
   
   ASSERT(pRecvFrame);
   ASSERT(peSealID);
      
   memcpy( peSealID, pRecvFrame->eSealID , FRAME_DATA_LTH_ESEALID);
}

void  GetReaderID(INT8U* pReaderID ,PHY_FRAME* pRecvPacket)
{
   WIRELESSPROTOCOL_P2P_UP_FRAME* pRecvFrame = (WIRELESSPROTOCOL_P2P_UP_FRAME*)pRecvPacket->PhyFrame;
   
   ASSERT(pRecvFrame);
   ASSERT(pReaderID);

   memcpy( pReaderID, pRecvFrame->ReaderID , FRAME_DATA_LTH_READERID);
}

INT8U  GetDataLength(PHY_FRAME* pRecvPacket)
{   
   WIRELESSPROTOCOL_P2P_UP_FRAME* pRecvFrame = (WIRELESSPROTOCOL_P2P_UP_FRAME*)pRecvPacket->PhyFrame;
   ASSERT(pRecvFrame);
   
   return pRecvFrame->DataLth ;
}

INT8U  GetCommand(PHY_FRAME* pRecvPacket)
{   
  WIRELESSPROTOCOL_P2P_UP_FRAME* pRecvFrame = (WIRELESSPROTOCOL_P2P_UP_FRAME*)pRecvPacket->PhyFrame; 
  
  ASSERT(pRecvFrame);
   
   return pRecvFrame->Command ;
}

INT8U  CheckCRC(PHY_FRAME* pRecvPacket)
{
   INT16U Crc;
   INT8U  DataLth;
   
   ASSERT(pRecvPacket);
   
   
   DataLth = pRecvPacket->PhyFrame[FRAME_P2P_UP_DATA_POS_DATALTH] ;
   Crc = Crc16((INT8U*)(pRecvPacket->PhyFrame) , FRAME_P2P_UP_DEFAULT_LTH + DataLth);
   if(Crc == *(INT16U*)(&pRecvPacket->PhyFrame[FRAME_P2P_UP_DATA_POS_DATA + DataLth]))
      return TRUE;
   else
      return FALSE;  
}

//----------------------------------------------------------------------------------
//  void  GetData(WIRELESSPROTOCOL_P2P_UP_FRAME* pRecvFrame, INT8U *pData)
//
//  DESCRIPTION:
//
//
//  ARGUMENTS:
//            WIRELESSPROTOCOL_P2P_UP_FRAME* pRecvFrame [In]  - 
//            INT8U *pData [In]                       -
//   RETURN:
//            None
//----------------------------------------------------------------------------------
void  GetData(WIRELESSPROTOCOL_P2P_UP_FRAME* pRecvFrame, INT8U *pData)
{
   
   ASSERT(pRecvFrame);
   ASSERT(pData);
   
   if(pRecvFrame->DataLth)
   {
      pData = pRecvFrame->pData;
   }
   else
      pData = NULL;
}

INT8U  CheckReaderID(PHY_FRAME* pRecvPacket)
{
   INT8U  ReaderID[FRAME_DATA_LTH_READERID];
   INT8U  i;
   
   ASSERT(pRecvPacket);
   
   GetReaderID(ReaderID , pRecvPacket);
   for( i = 0 ; i < FRAME_DATA_LTH_READERID ; i++)
   {
      if(ReaderID[i] != CurrentReaderID[i])
        break;
   }
   if(FRAME_DATA_LTH_READERID == i)
     return TRUE;
   else
     return FALSE;
}


